package me.yricky.alia.ui.layoutPage


import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.*
import androidx.compose.ui.res.useResource
import me.yricky.alia.data.base.Coord
import me.yricky.alia.data.base.angleRad
import me.yricky.alia.data.hierarchy.ArrayCellRef
import me.yricky.alia.data.hierarchy.CellRef
import me.yricky.alia.data.hierarchy.SingleCellRef
import me.yricky.alia.data.shape.Shape
import me.yricky.alia.ui.*
import me.yricky.alia.ui.layoutPage.renderModel.LayerRender
import org.jetbrains.skia.Image
import org.jetbrains.skia.Shader
import kotlin.math.PI

/**
 * @author Yricky
 * @date 2022/2/9
 */

val internalBrushes:Map<String, ShaderBrush> by lazy {
    mutableListOf("dot","hLine","vLine","grid","ltrbLine","rtlbLine","hComb","vComb").map {
        Pair(it, useResource("imgShader/$it.png"){
            Image
            ShaderBrush(
                ImageShader(
                    Image.makeFromEncoded(it.readAllBytes()).toComposeImageBitmap(),
                    TileMode.Repeated,
                    TileMode.Repeated
                )
            )
        })
    }.toMap()
}
val solidBrush = ShaderBrush(Shader.makeColor(Color.Black.toArgb()))

@Composable
fun LayerIcon(
    modifier: Modifier,
    brush: ShaderBrush,
    color: Color,
    stroke: Boolean,
    strokeWidth:Float,
    aa:Boolean
) = LayerIcon(modifier,LayerRender.LayerStyle(
    color, brush, stroke, strokeWidth, aa
))

@Composable
fun LayerIcon(modifier: Modifier,style: LayerRender.LayerStyle) {
    androidx.compose.foundation.Canvas(modifier) {
        val fillPaint =style.fillPaint(size)
        val strokePaint = style.strokePaint()
        drawContext.canvas.drawCircle(size.center,size.minDimension/2,fillPaint)
        if (style.stroke) {
            drawContext.canvas.drawCircle(size.center,size.minDimension/2,strokePaint)
        }
    }
}


inline fun useCoordDots(canvasBox: FBox, zoom:Float,usage:(Offset)->Unit){
    val zoomedBox = canvasBox.centerZoom(zoom)
    var step = 1
    while (step*zoom < 50){
        step *= 10
    }
    var x = zoomedBox.lt.x
    x -= x % step
    var y: Float

    while (x < zoomedBox.rb.x){
        y = zoomedBox.lt.y
        y -= y % step
        while (y < zoomedBox.rb.y){
            usage(Offset(x,y).relativeVertex(canvasBox.width,canvasBox.height,zoom,canvasBox.center))
            y += step
        }
        x += step
    }
}

fun Shape.needRender(dst:FBox):Boolean{
    return dst.isOverlap(this.bBox)
}

val CellRef.transformMatrix get() = Matrix().also {
    it.scale(mag.toFloat(),mag.toFloat())
    it.rotateZ(-rotCCWDeg.toFloat())
    it.translate(off.x.toFloat(),-off.y.toFloat())
}


fun ArrayCellRef.toCellRefs():List<SingleCellRef>{
    if(col == 1.toShort() && row == 1.toShort()){
        return listOf(SingleCellRef(name, off, mag, rotCCWDeg))
    }
    val xUnit = (coordX-off).divide(col.toInt())
    val yUInt = (coordY-off).divide(row.toInt())
    var angle = 0.0
    if(xUnit.abs()!= 0.0){
        angle = angleRad(Coord.X_UNIT,coordX-off) *180/ PI
    }
    val li = ArrayList<SingleCellRef>()

    val matrix = Matrix().also {
        it.scale(mag.toFloat(),mag.toFloat())
        it.rotateZ(-rotCCWDeg.toFloat()+angle.toFloat())
    }
    (0 until col).forEach { x->
        (0 until row).forEach { y->
            li.add(
                SingleCellRef(
                name,
                off - matrix.map((xUnit.multiply(x) + yUInt.multiply(y)).toOffset()).toCoord(),
                mag,
                rotCCWDeg-angle)
            )
        }
    }
    return li
}

